package org.hiberlyzer.ui;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Collection;

import javax.swing.JButton;
import javax.swing.JInternalFrame;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.JToolBar;

import org.hiberlyzer.DataColumn;
import org.hiberlyzer.DataSource;
import org.hiberlyzer.QueryLanguage;
import org.hiberlyzer.impl.CollectionDataColumn;
import org.hiberlyzer.impl.EntityDataColumn;

/**
 * Responsible for displaying query entry and result display UI. Queries are
 * executed against a supplied SessionProvider object and the presentation of
 * the results is handled by the ResultTableModelFactory.
 * 
 * @author BDotzour
 */
public class QueryWindow extends JInternalFrame
{
	private JTextArea queryTextArea;
	private StatsPanel statsPanel;
	private DataSource dataSource;
	private QueryLanguage currentQueryLanguage = QueryLanguage.HQL;
	private ResultView resultView = new ResultView(this);
	
	private QueryWindow()
	{
		super("", true, true, true, true);
		getContentPane().setLayout(new BorderLayout());
		setUpToolbar();
		setUpMainWindow();
		setUpStatsPanel();
		pack();
	}

	public QueryWindow(DataSource dataSource)
	{
		this();
		this.dataSource = dataSource;
		this.setTitle(dataSource.getDescription());
	}

	@Override
	public Dimension getPreferredSize()
	{
		return new Dimension(600, 400);
	}

	private void setUpStatsPanel()
	{
		this.statsPanel = new StatsPanel(currentQueryLanguage);
		getContentPane().add(statsPanel, BorderLayout.SOUTH);
	}

	private void setUpMainWindow()
	{
		JSplitPane mainPanel = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
		mainPanel.setDividerLocation(100); // just push the divider down a bit so it looks reasonable
		mainPanel.setDividerSize(5);
		mainPanel.setContinuousLayout(true); // nice redrawing as you drag the divider
		mainPanel.add(buildQueryPanel());
		mainPanel.add(resultView);
		getContentPane().add(mainPanel, BorderLayout.CENTER);
	}

	private void setUpToolbar()
	{
		JToolBar toolBar = new JToolBar();
		JButton runButton = new JButton("Run");
		runButton.addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				executeQuery();
			}
		});
		toolBar.add(runButton);

		final JButton translateButton = new JButton("Translate");
		translateButton.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e)
			{
					resultView.displayMessages(dataSource.translateHql(getQueryText()));
			}});
		toolBar.add(translateButton);
		
		toolBar.addSeparator();
		
		final JButton queryLanguageButton = new JButton(currentQueryLanguage.toString());
		queryLanguageButton.addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				if (currentQueryLanguage.equals(QueryLanguage.HQL))
				{
					currentQueryLanguage = QueryLanguage.SQL;
					translateButton.setEnabled(false);
				}
				else
				{
					currentQueryLanguage = QueryLanguage.HQL;
					translateButton.setEnabled(true);
				}
				queryLanguageButton.setText(currentQueryLanguage.toString());
			}
		});
		toolBar.add(queryLanguageButton);

		getContentPane().add(toolBar, BorderLayout.NORTH);
	}

	private Component buildQueryPanel()
	{
		queryTextArea = new JTextArea();
		queryTextArea.addKeyListener(new KeyAdapter()
		{
			public void keyReleased(KeyEvent e)
			{
				if (e.getKeyCode() == KeyEvent.VK_F5)
				{
					executeQuery();
				}
				else
				{
					super.keyTyped(e);
				}
			}
		});
		JScrollPane queryPanel = new JScrollPane(queryTextArea);
		return queryPanel;
	}

	private void executeQuery()
	{
		statsPanel.queryBegin();
		statsPanel.queryTypeChanged(currentQueryLanguage);
		resultView.clear();
		String queryText = getQueryText();
		resultView.displayResults(queryText, currentQueryLanguage, dataSource);
		statsPanel.queryEnd(resultView.getResultCount());
	}

	private String getQueryText()
	{
		return queryTextArea.getSelectedText() != null ? queryTextArea.getSelectedText() : queryTextArea.getText();
	}

	public void displayDetailDialog(Object value, DataColumn dataColumn)
	{
		if(dataColumn instanceof EntityDataColumn)
		{
	    	EntityDetailDialog dialog = new EntityDetailDialog(value, 
						(Frame) getTopLevelAncestor(), 
						dataSource.getMetadataSource());
	    	dialog.setLocationRelativeTo(this);
	    	dialog.setVisible(true);
		}
		else if(dataColumn instanceof CollectionDataColumn)
		{
			CollectionDetailDialog dialog = new CollectionDetailDialog((Collection) value, 
						(Frame) getTopLevelAncestor(),
						dataSource.getMetadataSource());
			dialog.setLocationRelativeTo(this);
			dialog.setVisible(true);
		}
	}
}
